package com.caiya.controller;

import com.caiya.dto.User;
import com.caiya.util.ExcelField;
import org.apache.poi.hssf.usermodel.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * Created by Administrator on 2018/11/15 0015.
 */
@RestController
@RequestMapping("/excl")
public class ExcelController {


    @GetMapping(value = "/list")
    public String list(HttpServletResponse response){

        List<User> list = new ArrayList<>();
        User user = new User();
        user.setName("liu");
        user.setAge("18");
        list.add(user);

        //反射，获取类对象
        Object obj = list.get(0);
        Class clazz = obj.getClass();

        //创建excel工作簿
        HSSFWorkbook wb = new HSSFWorkbook();
        //创建页 ，指定页的名字就是表名，excel有很多页
        HSSFSheet sheet = wb.createSheet(clazz.getSimpleName());
        //设置单元格样式,居中显示
        HSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);

        //222222222222222222222222222222222222222


        //获取字段对象
        Field[] fields = clazz.getDeclaredFields();

        //字段名数组,只需要标识了注解的字段
        List<String> names = new ArrayList<String>();
        for(int i=0,len=fields.length;i<len;i++){
            //获取字段是否有导出标识注解
            ExcelField field = fields[i].getAnnotation(ExcelField.class);
            if(field!=null) {
                //如果指定了列名，就使用列名，不然使用字段名
                if(field.title()!=null){
                    names.add(field.title());
                }else{
                    names.add(fields[i].getName());
                }
            }
        }

        //创建第一行
        HSSFRow row = sheet.createRow(0);
        for(int i=0,len=names.size();i<len;i++){
            //创建单元格
            HSSFCell cell = row.createCell(i);
            //指定值
            cell.setCellValue(names.get(i));
            //指定宽度
            sheet.setColumnWidth(i,5000);
            //设置样式
            cell.setCellStyle(style);
            //宽度自适应
            // sheet.autoSizeColumn(i);
        }

//3333333333333333333333333333333333333333333333333333333333
        for(int j=0,l=list.size();j<l;j++){
            Object temp = list.get(j);
            Class c = temp.getClass();
            Field[] fields1 = c.getDeclaredFields();
            //一个对象创建一个行,从第二行开始
            HSSFRow row1 = sheet.createRow(j+1);

            //用于作序号，因为循环的序号可能会发生有些属性不注入，序号就会断层
            //需要另外用变量来维持序号
            int k = 0;
            for(int i=0,len=fields1.length;i<len;i++){

                //只有 有标识注解的属性才导出
                ExcelField excelField = fields1[i].getAnnotation(ExcelField.class);
                if(excelField!=null) {

                    //根据指定的属性创建指定的单元格
                    HSSFCell cell = row1.createCell(k);

                    //设置值,因为不能直接放置Object，所以需要确定类型再转换
                    try {
                        fields1[i].setAccessible(true);
                        Object value = fields1[i].get(temp);
                        if (value instanceof String) {
                            cell.setCellValue(value.toString());
                        } else if (value instanceof Integer) {
                            cell.setCellValue((Integer) value);
                        } else if (value instanceof Double) {
                            cell.setCellValue((Double) value);
                        } else if (value instanceof Boolean) {
                            cell.setCellValue((Boolean) value);
                        } else if (value instanceof Float) {
                            cell.setCellValue((Float) value);
                        } else if (value instanceof Short) {
                            cell.setCellValue((Short) value);
                        } else if (value instanceof Character) {
                            cell.setCellValue((Character) value);
                        }
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException("类型转换错误");
                    }
                    //设置样式
                    cell.setCellStyle(style);

                    k++;
                }
            }
        }

        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        //文件名使用uuid，避免重复
        response.setHeader("Content-Disposition", "attachment;filename="
                + UUID.randomUUID() + ".xls");
        OutputStream ouputStream = null;
        try {
            ouputStream = response.getOutputStream();
            wb.write(ouputStream);
            ouputStream.flush();
            ouputStream.close();
        } catch (IOException e) {
            throw new RuntimeException("IO异常");
        }

        return "";
    }
}
